package cardsdk

import (
	"encoding/hex"

	"fmt"
	"os"
	"time"

	"gitee.com/fhe-search/nfhedecd/deviceKey"
	"gitee.com/fhe-search/nfhedecd/deviceManage"
	"gitee.com/fhe-search/nfhedecd/interfaceAPI"
	"gitee.com/fhe-search/nfhedecd/sessionKey"
)

// func NFHE_OpenDevice() error {
// 	var err error // 出错返回值
// 	rv := C.NFHE_OpenDevice()
// 	if rv != 0 {
// 		cw := fmt.Sprintf("%x", rv)
// 		err = errors.New("出错信息:打开设备时出错！错误号：" + cw)
// 	} else {
// 		return nil
// 	}
// 	return err
// }

// func NFHE_CloseDevice() error {
// 	var err error // 出错返回值
// 	rv := C.NFHE_CloseDevice()
// 	if rv != 0 {
// 		cw := fmt.Sprintf("%x", rv)
// 		err = errors.New("出错信息:关闭设备时出错！错误号：" + cw)
// 	} else {
// 		return nil
// 	}
// 	return err
// }

// NFHEDECDBackup 生成并备份一整套密钥
func NFHEDECDBackup() {
	var errMsg error
	PasswordGlobal := "1234567812345678"     // 初始化管理员口令
	PasswordGlobalLen := len(PasswordGlobal) // 口令长度
	now := time.Now()
	dateStr := now.Format("20060102")
	// 打印日期字符串
	fmt.Println(dateStr)
	filePathPrefix := "./huangheng" + dateStr + "/"
	// 尝试创建一个新目录
	err := os.MkdirAll(filePathPrefix+"SM1", 0755) // 第二个参数是权限，0755 表示目录对所有用户可读可执行，对所有者可读写执行
	if err != nil {
		fmt.Println("创建目录失败:", err)
	} else {
		fmt.Println("目录创建成功: " + filePathPrefix + "SM1")
	}
	err = os.MkdirAll(filePathPrefix+"UAP", 0755) // 第二个参数是权限，0755 表示目录对所有用户可读可执行，对所有者可读写执行
	if err != nil {
		fmt.Println("创建目录失败:", err)
	} else {
		fmt.Println("目录创建成功: " + filePathPrefix + "UAP")
	}

	// 1 备份保护密钥
	{
		var ProKeyvalue string
		ProKeyvalue, v2 := deviceKey.NFHE_DECD_ProKey_Backup(PasswordGlobal, PasswordGlobalLen)
		if v2 == nil {
			fmt.Println("1 备份保护密钥成功！")
		} else {
			fmt.Println(v2)
		}
		ProKeyvalue1, _ := hex.DecodeString(ProKeyvalue)
		errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+"./02_NFHE_DECD_ProKey.txt", ProKeyvalue1)
		if errMsg != nil {
			fmt.Println(errMsg)
		}
	}
	// 2 生成 与 备份用户密钥
	{
		v2 := deviceKey.NFHE_DECD_Create_UserKey(PasswordGlobal, PasswordGlobalLen, 1, "ABCDEFGH", 8)
		if v2 == nil {
			fmt.Println("2 生成用户密钥成功！")
		} else {
			fmt.Println(v2)
		}
		userKeyvalue, v2 := deviceKey.NFHE_DECD_UserKey_Backup(PasswordGlobal, PasswordGlobalLen)
		if v2 == nil {
			fmt.Println("2 备份用户密钥成功！")
		} else {
			fmt.Println(v2)
		}
		deviceKeyvalue1, _ := hex.DecodeString(userKeyvalue)
		errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+"./03_NFHE_DECD_UserKey.txt", deviceKeyvalue1)
		if errMsg != nil {
			fmt.Println(errMsg)
		}
	}

	// 3 生成 与 备份密钥加密密钥
	{
		v2 := deviceKey.NFHE_DECD_Create_KEK(PasswordGlobal, PasswordGlobalLen, 0)
		if v2 == nil {
			fmt.Println("3 生成密钥加密密钥成功！")
		} else {
			fmt.Println(v2)
		}
		var KEKvalue string
		KEKvalue, v2 = deviceKey.NFHE_DECD_KEK_Backup(PasswordGlobal, PasswordGlobalLen)
		if v2 == nil {
			fmt.Println("3 备份密钥加密密钥成功！")
		} else {
			fmt.Println(v2)
		}
		KEKvalue1, _ := hex.DecodeString(KEKvalue)
		errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+"./04_NFHE_DECD_KEK.txt", KEKvalue1)
		if errMsg != nil {
			fmt.Println(errMsg)
		}
	}
	// 备份会话密钥 同态公私钥 + SM1密钥
	// 4 生成与备份同态公私钥对
	{
		FHEPubKeyValue, FHEPriKeyValue, v2 := sessionKey.FHEKmg_Create_FheKey(1)
		if v2 == nil {
			fmt.Println("4 生成同态公私钥成功！")
		} else {
			fmt.Println(v2)
		}
		FHEPubKeyValue1, _ := hex.DecodeString(FHEPubKeyValue)
		errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+"./05_NFHE_DECD_FHEKey.txt", FHEPubKeyValue1)
		if errMsg != nil {
			fmt.Println(errMsg)
		}
		FHEPriKeyValue1, _ := hex.DecodeString(FHEPriKeyValue)
		errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+"./06_NFHE_DECD_FHE_priKey.txt", FHEPriKeyValue1)
		if errMsg != nil {
			fmt.Println(errMsg)
		}
		fmt.Println("4 备份同态公私钥成功！")

	}

	// 5 生成与备份SM1密钥
	{
		var i uint
		for i = 0; i < 64; i++ {
			v2 := sessionKey.NFHE_DECD_Create_SM1(i)
			if v2 != nil {
				fmt.Println(v2)
				break
			}
		}
		fmt.Println("5 生成SM1密钥成功！")
		for i = 0; i < 64; i++ {
			SM1Key_value, v2 := sessionKey.NFHE_DECD_Backup_SM1(i)
			if v2 != nil {
				fmt.Println(v2)
				break
			}
			SM1Key_value1, _ := hex.DecodeString(SM1Key_value)
			s := fmt.Sprintf("%d", i)
			Ls_File_Name := "./SM1/07_NFHE_DECD_SM1_Key"
			Ls_File_Name += s
			Ls_File_Name = Ls_File_Name + ".txt"
			errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+Ls_File_Name, SM1Key_value1)
			if errMsg != nil {
				fmt.Println(errMsg)
			}
		}
		if errMsg == nil {
			fmt.Println("5 备份SM1密钥成功！")
		}
	}

	// 6 创建 并 备份用户权限口令
	{
		var i uint
		for i = 0; i < 64; i++ {
			v2 := sessionKey.NFHE_DECD_Create_Auth(i)
			if v2 != nil {
				fmt.Println(v2)
				break
			}
		}
		fmt.Println("6 生成用户权限成功！")
		for i = 0; i < 64; i++ {
			Auth_value, v2 := sessionKey.NFHE_DECD_Backup_Auth(i)
			if v2 != nil {
				fmt.Println(v2)
				break
			}
			Auth_value1, _ := hex.DecodeString(Auth_value)
			s := fmt.Sprintf("%d", i)
			Ls_File_Name := "./UAP/08_NFHE_DECD_Auth"
			Ls_File_Name += s
			Ls_File_Name = Ls_File_Name + ".txt"
			errMsg = interfaceAPI.FileWriteKeyByte(filePathPrefix+Ls_File_Name, Auth_value1)
			if errMsg != nil {
				fmt.Println(errMsg)
			}
		}
		fmt.Println("6 备份用户权限口令成功！")
	}
}

// NFHEDECDInit 恢复一整套密钥
func NFHEDECDInit(fileNamePrefix string) {
	var errMsg error
	PasswordGlobal := "1234567812345678"     // 初始化管理员口令
	PasswordGlobalLen := len(PasswordGlobal) // 口令长度

	// 0-1 设备恢复出厂状态
	errMsg = deviceManage.DECD_Restore_FactorySetting(PasswordGlobal, PasswordGlobalLen)
	if errMsg == nil {
		fmt.Println("0-1 提示: 设备恢复出厂状态成功！")
	} else {
		panic(errMsg)
	}
	// 0-2 初始化设备
	errMsg = deviceManage.DECD_Kmg_Init_Device(PasswordGlobal, PasswordGlobalLen)
	if errMsg == nil {
		fmt.Println("0-2 提示: 初始化设备成功！")
	} else {
		panic(errMsg)
	}
	// 1 恢复保护密钥
	{
		var ProKeyvalue []byte
		ProKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./02_NFHE_DECD_ProKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg := deviceKey.NFHE_DECD_Prokey_Restore(PasswordGlobal, PasswordGlobalLen, ProKeyvalue)
		if errMsg == nil {
			//fmt.Println("1 恢复保护密钥成功！", strings.ToUpper(hex.EncodeToString(ProKeyvalue[0:116])))
			fmt.Println("1 恢复保护密钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 2 恢复用户密钥
	{
		var UserKeyvalue []byte
		UserKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./03_NFHE_DECD_UserKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg := deviceKey.NFHE_DECD_UserKey_Restore(PasswordGlobal, PasswordGlobalLen, UserKeyvalue)
		if errMsg == nil {
			//fmt.Println("2 恢复用户密钥成功！", strings.ToUpper(hex.EncodeToString(UserKeyvalue[0:192])))
			fmt.Println("2 恢复用户密钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 3 恢复密钥加密密钥
	{
		var KEKvalue []byte
		KEKvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./04_NFHE_DECD_KEK.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg := deviceKey.NFHE_DECD_KEK_Restore(PasswordGlobal, PasswordGlobalLen, KEKvalue)
		if errMsg == nil {
			//fmt.Println("3 恢复密钥加密密钥成功！", strings.ToUpper(hex.EncodeToString(KEKvalue[0:16])))
			fmt.Println("3 恢复密钥加密密钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 4 恢复同态公私钥对
	{
		//导入会话密钥
		var FHEPubKeyvalue []byte
		var FHEPriKeyvalue []byte
		FHEPubKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./05_NFHE_DECD_FHEKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		FHEPriKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./06_NFHE_DECD_FHE_priKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg = sessionKey.NFHE_DECD_Import_FHE_Key(1, FHEPubKeyvalue, FHEPriKeyvalue)
		if errMsg == nil {
			fmt.Println("4 恢复同态公钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 5 恢复SM1密钥
	{
		var i uint
		for i = 0; i < 64; i++ {
			s := fmt.Sprintf("%d", i)
			Ls_File_Name := "./SM1/07_NFHE_DECD_SM1_Key"
			Ls_File_Name += s
			Ls_File_Name = Ls_File_Name + ".txt"
			SM1Key_value, errMsg := interfaceAPI.FileReadKeyByte(fileNamePrefix + Ls_File_Name)
			if errMsg != nil {
				panic(errMsg)
			}
			errMsg = sessionKey.NFHE_DECD_Restore_SM1(i, SM1Key_value)
			if errMsg != nil {
				panic(errMsg)
			}
		}
		fmt.Println("5 恢复SM1密钥成功！")
	}

	// 6 恢复用户口令
	{
		var i uint
		for i = 0; i < 64; i++ {
			s := fmt.Sprintf("%d", i)
			Ls_File_Name := "./UAP/08_NFHE_DECD_Auth"
			Ls_File_Name += s
			Ls_File_Name = Ls_File_Name + ".txt"
			Auth_value, errMsg := interfaceAPI.FileReadKeyByte(fileNamePrefix + Ls_File_Name)
			//User_Auth_Password[i] = strings.ToUpper(hex.EncodeToString(Auth_value)[0:16])
			if errMsg != nil {
				panic(errMsg)
			}
			errMsg = sessionKey.NFHE_DECD_Restore_Auth(i, Auth_value)
			if errMsg != nil {
				panic(errMsg)
			}
		}
		fmt.Println("6 恢复用户权限口令成功！")
	}
}
